在上一小节中我们使用 Vite 初始化了一个 Web 项目,迈出了使用 Vite 的第一步。但在实际的场景中,仅仅用 Vite 官方的脚手架项目往往不够,还需要考虑诸多的工程化因素,借助 Vite 本身的配置以及业界的各种生态,才能搭建一个名副其实的脚手架工程。
与文档的平铺直叙不同,在接下来的几个小节内容中我们将以实战的方式逐个击破项目工程化的要素。你可以跟着我一起进行编码,真真切切的从0搭建一个完整的 Vite 项目架构。不仅如此,在实战的过程中,你也会对 Vite 本身的功能有全面的了解,能够熟练地将 Vite 应用在实际的项目中。
样式方案是前端工程化离不开的一个话题,也是本节要具体探讨的内容。在最原始的开发阶段大家都是手写原生的 CSS,但原生 CSS 的问题存在着诸多问题,在这个小节中我将会给你一一梳理这些问题,并引入现代的各种 CSS 样式方案,然后一起进行动手实践,让你学会如何在 Vite 中落地各种样式方案。
# 样式方案的意义
对初学者来说,谈到开发前端的样式,首先想到的便是直接写原生的 CSS,但时间一长,难免会发现原生 CSS 开发的各种问题,接下来我们就来梳理一下如果不用任何 CSS 工程方案,到底会出现哪些问题:
- 开发体验欠佳。比如原生 CSS 不支持选择器的嵌套:
// 选择器只能平铺,不能嵌套
.container .header .nav .title .text {
color: blue;
}
.container .header .nav .box {
color: blue;
border: 1px solid grey;
}
- 样式污染问题。如果出现同样的类名,很容易造成不同的样式互相覆盖和污染。
// a.css
.container {
color: red;
}
// b.css
// 很有可能覆盖 a.css 的样式!
.container {
color: blue;
}
- 浏览器兼容问题。为了兼容不同的浏览器,我们需要对一些属性(如
transition)加上不同的浏览器前缀,比如-webkit-、-moz-、-ms-、-o-,意味着开发者要针对同一个样式属性写很多的冗余代码。 - 打包后的代码体积问题。如果不用任何的 CSS 工程化方案,那么所有的 CSS 代码都将打包到产物中,即使有部分样式并没有在代码中使用,导致产物体积过大。
针对如上原生 CSS 的痛点,社区中诞生了不少的解决方案,常见的有这么几类:
CSS 预处理器,主流的包括Sass/Scss、Less和Stylus,这些方案各自定义了一套语法,让 CSS 也能使用嵌套规则,甚至能像编程语言一样定义变量、写条件判断和循环语句,大大增强了样式语言的灵活性,解决原生 CSS 的开发体验问题。CSS Modules,会将 CSS 类名处理成哈希值,这样就可以避免同名的情况下样式污染的问题。- CSS 后处理器
PostCSS,用来解析和处理 CSS 代码,可以实现的功能非常丰富,比如将px转换为rem、根据目标浏览器情况自动加上类似于--moz--、-o-的属性前缀等等。 CSS in JS方案,主流的包括emotion、styled-components等等,顾名思义,这类方案可以实现直接在 JS 中写样式代码,基本包含CSS 预处理器和CSS Modules的各项优点,非常灵活,解决了开发体验和全局样式污染的问题。- CSS 原子化框架,如
Tailwind CSS、Windi CSS,通过类名来指定样式,大大简化了样式写法,提高了样式开发的效率,主要解决了原生 CSS 开发体验的问题。
不过,各种方案没有孰优孰劣,各自解决的方案有重叠的部分,但也有一定的差异,大家可以根据自己项目的痛点来引入。接下来,我们就进入实战的阶段,在 Vite 中来应用上述这些常见的 CSS 方案。
# CSS 预处理器
Vite 本身对 CSS 各种预处理器语言(Sass/Scss、Less和Stylus)作了内置的支持,也就是说,即使你不经过任何的配置也可以直接使用各种 CSS 预处理器。接下来我们以 Sass/Scss 为例,来具体感受一下 Vite 的零配置给我们带来的便利。
由于 Vite 底层会调用 CSS 预处理器的官方库进行编译,而 Vite 为了实现按需加载,并没有内置这些工具库,而是让用户根据需要地安装,因此我们首先来安装 Sass 的官方库,安装命令如下所示:
